package org.finesys.common.security.authentication.converter;

import java.io.IOException;
import java.util.Map;

import org.finesys.common.core.util.SpringUtil;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.GenericHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.oauth2.core.endpoint.DefaultOAuth2AccessTokenResponseMapConverter;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 扩展原生的实现，支持 Long2String
 */
public class CustomOAuth2AccessTokenResponseHttpMessageConverter extends OAuth2AccessTokenResponseHttpMessageConverter {

    private static final ParameterizedTypeReference<Map<String, Object>> STRING_OBJECT_MAP = new ParameterizedTypeReference<Map<String, Object>>() {
    };

    private Converter<OAuth2AccessTokenResponse, Map<String, Object>> accessTokenResponseMapConverter = new DefaultOAuth2AccessTokenResponseMapConverter();


    @Override
    protected void writeInternal(OAuth2AccessTokenResponse tokenResponse, HttpOutputMessage outputMessage) throws HttpMessageNotWritableException {
        try {
            Map<String, Object> tokenResponseParameter = this.accessTokenResponseMapConverter.convert(tokenResponse);
            ObjectMapper objectMapper = SpringUtil.getBean(ObjectMapper.class);
            GenericHttpMessageConverter<Object> jsonMessageConverter = new MappingJackson2HttpMessageConverter(objectMapper);
            jsonMessageConverter.write(tokenResponseParameter, STRING_OBJECT_MAP.getType(), MediaType.APPLICATION_JSON, outputMessage);
        } catch (IOException e) {
            throw new HttpMessageNotWritableException("An error occurred writing the OAuth 2.0 access Token Response:" + e.getMessage(), e);
        }
    }
}
